package net.shambolica.ember.jinterface.wrappers.objects.patterns;

import com.ericsson.otp.erlang.*;
import net.shambolica.ember.jinterface.wrappers.objects.EOMatch;
import net.shambolica.ember.jinterface.wrappers.objects.EOPattern;

import java.util.Arrays;
import java.util.Collection;
import java.util.Map;

/**
 * Patterns for is_X predicates.
 */
public class EOPIsA extends EOPattern {

    /* Useful members */

    public static final EOPIsA isAtom = new EOPIsA(OtpErlangAtom.class);
    public static final EOPIsA isBinary = new EOPIsA(OtpErlangBinary.class);
    public static final EOPIsA isList = new EOPIsA(OtpErlangList.class, OtpErlangString.class);
    public static final EOPIsA isNumber = new EOPIsA(OtpErlangLong.class, OtpErlangDouble.class);
    public static final EOPIsA isPid = new EOPIsA(OtpErlangPid.class);
    public static final EOPIsA isRef = new EOPIsA(OtpErlangRef.class);
    public static final EOPIsA isTuple = new EOPIsA(OtpErlangTuple.class);

    /* The basic code */

    private final Collection<Class> classes;

    protected EOPIsA(Collection<Class> classes) {
        if (classes == null) {
            throw new IllegalArgumentException("null classes collection for isa predicate");
        }
        this.classes = classes;
    }

    protected EOPIsA(Class ... classes) {
        this(Arrays.asList(classes));
    }

    @Override
    public Map<String, OtpErlangObject> match(OtpErlangObject term, Map<String, OtpErlangObject> acc) {
        for (Class clazz: classes) if (clazz.isInstance(term)) return mkAcc(acc);
        return null;
    }

    @Override
    public boolean isAbstract() {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

}
